home *** CD-ROM | disk | FTP | other *** search
/ Internet Publisher's Toolbox 2.0 / Internet Publisher's Toolbox.iso / internet / ntserver / wtsource / transprt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-16  |  12.4 KB  |  478 lines

  1. /* WIDE AREA INFORMATION SERVER SOFTWARE:
  2.    No guarantees or restrictions.  See the readme file for the full standard
  3.    disclaimer.
  4. */
  5.  
  6. /* Copyright (c) CNIDR (see ../COPYRIGHT) */
  7.  
  8.  
  9. #ifndef lint
  10. static char *RCSid = "$Header: /usr/users/freewais/FreeWAIS-0.1/ir/transprt.c,v 1.1 1993/02/16 15:05:35 freewais Exp $";
  11. #endif
  12.  
  13. /* this is a krufty transport layer for comm mediums that can not handle
  14.  * all 8 bits of ascii.
  15.  * Written by Harry Morris, modified by brewster.
  16.  * Hexcode written by Steve Swartz
  17.  * 
  18.  */
  19.  
  20. /* to do
  21.  *
  22.  *  compression
  23.  *  encryption
  24.  */
  25.  
  26. /* Change log:
  27.  * $Log: transprt.c,v $
  28.  * Revision 1.1  1993/02/16  15:05:35  freewais
  29.  * Initial revision
  30.  *
  31.  * Revision 1.2  92/02/12  13:51:34  jonathan
  32.  * Added "$Log" so RCS will put the log message in the header
  33.  * 
  34.  * 
  35.  * 7/7/90 -brewster
  36.  * merged arts and harry's changes 7/7/90 -brewster
  37.  *
  38.  * 11/6/90 -tracy
  39.  * shift 6 bytes starting from [ as IBM gateway program
  40.  * masks out characters [\]^` in input,
  41.  * append H and I to the function names corresponding to the
  42.  * oroginal coding and the modified one. 'I' indicates IBM. 
  43.  */
  44.  
  45. #include "transprt.h"
  46. #include "wmessage.h" 
  47. #include "ustubs.h"
  48.  
  49. /*---------------------------------------------------------------------*/
  50. static char alphaH[] = /* Must be 65 consecutive ascii characters */
  51.   "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnop";
  52.  
  53.  
  54. /*---------------------------------------------------------------------*/
  55.  
  56. static void hexCodeH _AP((char* data,long* len));
  57.  
  58. static void
  59. hexCodeH(data,len)
  60. char* data;
  61. long* len;
  62. /* compose a message for sending over ascii terminal lines. Input is '*len'
  63.  * binary bytes; output is 'ceiling(*len/3) * 4' characters from alpha[].
  64.  *
  65.  * Encoding goes like this. Let capital letters represent bits:
  66.  * Input bytes:  ABCDEFGH IJKLMNOP QRSTUVWX
  67.  * Output chars: alpha[CDEFGH] alpha[ABIJKL] alpha[QRMNOP] alpha[SRUVWX]
  68.  *
  69.  * 1 byte at end: ABCDEFGH
  70.  * Output chars:  alpha[CDEFGH] alpha[AB0000] alpha[1000000] alpha [1000000]
  71.  *
  72.  * 2 bytes at end: ABCDEFGH IJKLMNOP
  73.  * Output chars:   alpha[CDEFGH] alpha[ABIJKL] alpha[00MNOP] alpha [1000000]
  74.  */
  75. {
  76.   long i, j;
  77.   
  78.   switch (*len % 3)
  79.     {
  80.     case 2:
  81.       i = *len; j = (*len+1)/3 * 4 - 1; *len = j + 1;
  82.       data[j]   = alphaH[64];
  83.       data[j-1] = alphaH[data[i-1] & 0x0f];
  84.       data[j-2] = alphaH[(data[i-2] & 0xc0) >> 2 | (data[i-1] & 0xf0) >> 4];
  85.       data[j-3] = alphaH[data[i-2] & 0x3F];
  86.       break;
  87.     case 1:
  88.       i = *len + 1; j = (*len+2)/3 * 4 - 1; *len = j + 1;
  89.       data[j]   = alphaH[64];
  90.       data[j-1] = alphaH[64];
  91.       data[j-2] = alphaH[(data[i-2] & 0xc0) >> 2];
  92.       data[j-3] = alphaH[data[i-2] & 0x3F];
  93.       break;
  94.     default:
  95.       i = *len + 2; j = (*len)/3 * 4 + 3; *len = j - 3;
  96.       break;
  97.     }
  98.   
  99.   for (i -= 3, j -= 4; i > 0; i -= 3, j -= 4)
  100.     { 
  101.       data[j]   = alphaH[data[i] & 0x3F];
  102.       data[j-1] = alphaH[(data[i] & 0xc0) >> 2 | (data[i-1] & 0x0f)];
  103.       data[j-2] = alphaH[(data[i-2] & 0xc0) >> 2 | (data[i-1] & 0xf0) >> 4];
  104.       data[j-3] = alphaH[data[i-2] & 0x3F];
  105.     }
  106. }
  107.  
  108. /*---------------------------------------------------------------------*/
  109.  
  110. static void hexDecodeH _AP((char* data,long* len));
  111.  
  112. static void
  113. hexDecodeH(data,len)
  114. char* data;
  115. long* len;
  116. /* Incoming data is 'len' letters from alpha[] created by hexCode(). 'len'
  117.  *  will always be divisble by 4. Output is the binary bytes that were 
  118.  *  encoded into 'data'.
  119.  *
  120.  * If alpha[] isn't consecutive ascii characters, then the function moving 
  121.  *  from ascii data to the 'bX' values has to become more complicated than
  122.  *  data[] - alpha[0].
  123.  */
  124. {
  125.   unsigned char b0, b1, b2, b3;
  126.   long i, j;
  127.  
  128.   
  129.   for (i = 3, j = 4; j < *len; i += 3, j += 4)
  130.     {
  131.       b0 = (data[j-4] & 0x07F) - alphaH[0];
  132.       b1 = (data[j-3] & 0x07F) - alphaH[0];
  133.       b2 = (data[j-2] & 0x07F) - alphaH[0];
  134.       b3 = (data[j-1] & 0x07F) - alphaH[0];
  135.       data[i-3] = b0 | (b1 & 0x30) << 2;
  136.       data[i-2] = (b1 & 0x0f) << 4 | (b2 & 0x0f);
  137.       data[i-1] = b3 | (b2 & 0x30) << 2;
  138.     }
  139.  
  140.   *len = *len/4 * 3 - 2;
  141.   b0 = (data[j-4] & 0x07F) - alphaH[0];
  142.   b1 = (data[j-3] & 0x07F) - alphaH[0];
  143.   b2 = (data[j-2] & 0x07F) - alphaH[0];
  144.   b3 = (data[j-1] & 0x07F) - alphaH[0];
  145.   data[i-3] = b0 | (b1 & 0x30) << 2;
  146.  
  147.   if (b2 != 64)    
  148.     {
  149.       data[i-2] = (b1 & 0x0f) << 4 | (b2 & 0x0f);
  150.       (*len)++;
  151.     }
  152.  
  153.   if (b3 != 64)
  154.     {
  155.       data[i-1] = b3 | (b2 & 0x30) << 2;
  156.       (*len)++;
  157.     }
  158. }
  159.  
  160. /*---------------------------------------------------------------------*/
  161.  
  162. void
  163. transportCodeH(data,len)
  164. char* data;
  165. long* len;
  166. /* krufty serial line transport layer - encode in hex and append in cr */
  167. /* Now it also writes a wais packet header on to the front of the packet.
  168.  *   --art 
  169.  */
  170.   hexCodeH(data,len);
  171.   data[*len] = '\r';
  172.   data[*len + 1] = '\0';
  173.   *len += 1;
  174. }
  175.  
  176. /*---------------------------------------------------------------------*/
  177.  
  178. void
  179. transportDecodeH(data,len)
  180. char* data;
  181. long* len;
  182. /* decode above */
  183. /* This does not have to deal with the wais packet header since it has
  184.    been removed at the end of the read.  */
  185.   if (*len == 0)
  186.     return;
  187.     
  188.   *len -= 1;
  189.   hexDecodeH(data,len);
  190. }
  191.  
  192. /*---------------------------------------------------------------------
  193.  Below are the set of transport coding/decoding functions for clients
  194.  dialing through IBM to DowQuest. Unlike the above one that
  195.  uses 65 consecutive ASCII character for the coding/decoding table,
  196.  table entries after charcater 'Z' are shift 6 characters.
  197.  *--------------------------------------------------------------------*/ 
  198.  
  199. #define LAST_NON_SHIFT_CHAR 90
  200. #define SHIFT_OFFSET   6
  201.  
  202. static char alphaI[] = 
  203.   "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv";
  204.  
  205.  
  206. static void hexCodeI _AP((char* data,long* len));
  207.  
  208. static void
  209. hexCodeI(data,len)
  210. char* data;
  211. long* len;
  212. /* compose a message for sending over ascii terminal lines. Input is '*len'
  213.  * binary bytes; output is 'ceiling(*len/3) * 4' characters from alpha[].
  214.  *
  215.  * Encoding goes like this. Let capital letters represent bits:
  216.  * Input bytes:  ABCDEFGH IJKLMNOP QRSTUVWX
  217.  * Output chars: alpha[CDEFGH] alpha[ABIJKL] alpha[QRMNOP] alpha[SRUVWX]
  218.  *
  219.  * 1 byte at end: ABCDEFGH
  220.  * Output chars:  alpha[CDEFGH] alpha[AB0000] alpha[1000000] alpha [1000000]
  221.  *
  222.  * 2 bytes at end: ABCDEFGH IJKLMNOP
  223.  * Output chars:   alpha[CDEFGH] alpha[ABIJKL] alpha[00MNOP] alpha [1000000]
  224.  */
  225. {
  226.   long i, j;
  227.   
  228.   switch (*len % 3)
  229.     {
  230.     case 2:
  231.       i = *len; j = (*len+1)/3 * 4 - 1; *len = j + 1;
  232.       data[j]   = alphaI[64];
  233.       data[j-1] = alphaI[data[i-1] & 0x0f];
  234.       data[j-2] = alphaI[(data[i-2] & 0xc0) >> 2 | (data[i-1] & 0xf0) >> 4];
  235.       data[j-3] = alphaI[data[i-2] & 0x3F];
  236.       break;
  237.     case 1:
  238.       i = *len + 1; j = (*len+2)/3 * 4 - 1; *len = j + 1;
  239.       data[j]   = alphaI[64];
  240.       data[j-1] = alphaI[64];
  241.       data[j-2] = alphaI[(data[i-2] & 0xc0) >> 2];
  242.       data[j-3] = alphaI[data[i-2] & 0x3F];
  243.       break;
  244.     default:
  245.       i = *len + 2; j = (*len)/3 * 4 + 3; *len = j - 3;
  246.       break;
  247.     }
  248.   
  249.   for (i -= 3, j -= 4; i > 0; i -= 3, j -= 4)
  250.     { 
  251.       data[j]   = alphaI[data[i] & 0x3F];
  252.       data[j-1] = alphaI[(data[i] & 0xc0) >> 2 | (data[i-1] & 0x0f)];
  253.       data[j-2] = alphaI[(data[i-2] & 0xc0) >> 2 | (data[i-1] & 0xf0) >> 4];
  254.       data[j-3] = alphaI[data[i-2] & 0x3F];
  255.     }
  256. }
  257.  
  258. /*---------------------------------------------------------------------*/
  259.  
  260. static void hexDecodeI _AP((char* data,long * len));
  261.  
  262. static void
  263. hexDecodeI(data,len)
  264. char* data;
  265. long* len;
  266. /* Incoming data is 'len' letters from alpha[] created by hexCode(). 'len'
  267.  *  will always be divisble by 4. Output is the binary bytes that were 
  268.  *  encoded into 'data'.
  269.  *
  270.  * If alpha[] isn't consecutive ascii characters, then the function moving 
  271.  *  from ascii data to the 'bX' values has to become more complicated than
  272.  *  data[] - alpha[0].
  273.  */
  274. {
  275.   unsigned char b0, b1, b2, b3;
  276.   long i, j;
  277.  
  278.   for ( i=0; i < *len ; i++ )
  279.     if ( data[i] > LAST_NON_SHIFT_CHAR ) data[i] -= SHIFT_OFFSET;
  280.   
  281.   for (i = 3, j = 4; j < *len; i += 3, j += 4)
  282.     {
  283.       b0 = (data[j-4] & 0x07F) - alphaI[0];
  284.       b1 = (data[j-3] & 0x07F) - alphaI[0];
  285.       b2 = (data[j-2] & 0x07F) - alphaI[0];
  286.       b3 = (data[j-1] & 0x07F) - alphaI[0];
  287.       data[i-3] = b0 | (b1 & 0x30) << 2;
  288.       data[i-2] = (b1 & 0x0f) << 4 | (b2 & 0x0f);
  289.       data[i-1] = b3 | (b2 & 0x30) << 2;
  290.     }
  291.  
  292.   *len = *len/4 * 3 - 2;
  293.   b0 = (data[j-4] & 0x07F) - alphaI[0];
  294.   b1 = (data[j-3] & 0x07F) - alphaI[0];
  295.   b2 = (data[j-2] & 0x07F) - alphaI[0];
  296.   b3 = (data[j-1] & 0x07F) - alphaI[0];
  297.   data[i-3] = b0 | (b1 & 0x30) << 2;
  298.  
  299.   if (b2 != 64)    
  300.     {
  301.       data[i-2] = (b1 & 0x0f) << 4 | (b2 & 0x0f);
  302.       (*len)++;
  303.     }
  304.  
  305.   if (b3 != 64)
  306.     {
  307.       data[i-1] = b3 | (b2 & 0x30) << 2;
  308.       (*len)++;
  309.     }
  310. }
  311.  
  312. /*---------------------------------------------------------------------*/
  313.  
  314. void
  315. transportCodeI(data,len)
  316. char* data;
  317. long* len;
  318. /* krufty serial line transport layer - encode in hex and append in cr */
  319. /* Now it also writes a wais packet header on to the front of the packet.
  320.  *   --art 
  321.  */
  322.   hexCodeI(data,len);
  323.   data[*len] = '\r';
  324.   data[*len + 1] = '\0';
  325.   *len += 1;
  326. }
  327.  
  328. /*---------------------------------------------------------------------*/
  329.  
  330. void
  331. transportDecodeI(data,len)
  332. char* data;
  333. long* len;
  334. /* decode above */
  335. /* This does not have to deal with the wais packet header since it has
  336.    been removed at the end of the read.  */
  337.   if (*len == 0)
  338.     return;
  339.     
  340.   *len -= 1;
  341.   hexDecodeI(data,len);
  342. }
  343.  
  344. /*---------------------------------------------------------------------*/
  345.  
  346.  
  347. #ifdef NOTDEFINED /* here for back compatibility */
  348.  
  349. static void hexCode _AP((char* data,long * len));
  350.  
  351. static void
  352. hexCode(data,len)
  353. char* data;
  354. long* len;
  355. /* compose a message for sending over ascii terminal lines.  The data is hex,
  356.  */
  357. { long i;
  358.   for (i = *len-1; i >= 0; i--)
  359.     { data[i*2+1] = (data[i]&0x0F) + 'a';
  360.       data[i*2] = ((data[i]>>4)&0x0F) + 'a';
  361.     }
  362.   data[*len*2] = '\0';
  363.   *len = *len * 2;
  364. }
  365.  
  366. /*---------------------------------------------------------------------------*/
  367.  
  368. static void hexDecode _AP((char* data,long * len));
  369.  
  370. static void
  371. hexDecode(data,len)
  372. char* data;
  373. long* len;
  374. /* converts a buffer full of dataLen bytes of hex in place into the
  375. equivalent binary form. len is filled with the actual number of binary bytes.
  376.  */
  377. { long i;
  378.   *len = *len / 2;
  379.   for (i = 0; i < *len; i++)
  380.     { long temp = 0;
  381.       temp = (data[i*2]-'a')<<4;
  382.       temp += data[i*2+1]-'a';
  383.       data[i] = (char)temp;
  384.     }
  385.   data[*len] = '\0';
  386. }
  387.  
  388. #endif /* def NOTDEFINED */
  389. /*---------------------------------------------------------------------------*/
  390.  
  391. boolean
  392. transportCode(encoding,data,len)
  393. long encoding;
  394. char* data;
  395. long* len;
  396. /* krufty serial line transport layer - encode in hex and add trailing nl */
  397. {
  398.   switch (encoding){
  399.   case NO_ENCODING:
  400.     /* do nothing */
  401.     return(true);
  402.   case HEX_ENCODING:
  403.     transportCodeH(data,len);
  404.     return(true);
  405.   case IBM_HEXCODING:
  406.     transportCodeI(data,len);
  407.     return(true);
  408.   default:
  409.     return(false);
  410.   }
  411. }
  412.  
  413. /*---------------------------------------------------------------------------*/
  414.  
  415. boolean
  416. transportDecode(encoding,data,len)
  417. long encoding;
  418. char* data;
  419. long* len;
  420. /* decode above */
  421. {
  422.   switch (encoding){
  423.   case NO_ENCODING:
  424.     /* do nothing */
  425.     return(true);
  426.   case HEX_ENCODING:
  427.     transportDecodeH(data,len);
  428.     return(true);
  429.   case IBM_HEXCODING:
  430.     transportDecodeI(data,len);
  431.     return(true);
  432.   default:
  433.     return(false);
  434.   }
  435. }
  436.  
  437. /*---------------------------------------------------------------------------*/
  438.  
  439.  
  440.  
  441.  
  442.  
  443.  
  444. #ifdef old /* from the bad old days */
  445.  
  446.  
  447. /*---------------------------------------------------------------------------*/
  448.  
  449. void
  450. transportCode(data,len)
  451. char* data;
  452. long* len;
  453. /* krufty serial line transport layer - encode in hex and add trailing nl */
  454. {
  455.   hexCode(data,len);
  456.   data[*len] = '\r';
  457.   data[*len+1] = '\0';
  458. }
  459.  
  460. /*---------------------------------------------------------------------------*/
  461.  
  462. void
  463. transportDecode(data,len)
  464. char* data;
  465. long* len;
  466. /* decode above */
  467. {
  468.   hexDecode(data,len);
  469. }
  470.  
  471. /*---------------------------------------------------------------------------*/
  472.  
  473. #endif /* old */
  474.